package org.wu.spring.orm.integration.compare.controller;

import org.wu.framework.easy.excel.stereotype.EasyFile;
import org.wu.framework.lazy.orm.database.lambda.domain.LazyPage;
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
import org.wu.framework.lazy.orm.database.lambda.stream.wrapper.LazyWrappers;
import org.wu.framework.web.response.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.wu.framework.core.NormalUsedString;
import org.wu.framework.core.utils.DataTransformUntil;
import org.wu.framework.web.response.ResultFactory;
import org.wu.framework.web.spring.EasyController;
import org.wu.spring.orm.integration.compare.application.SysUserApplication;
import org.wu.spring.orm.integration.compare.application.command.sys.user.SysUserQueryListCommand;
import org.wu.spring.orm.integration.compare.application.command.sys.user.SysUserQueryOneCommand;
import org.wu.spring.orm.integration.compare.application.command.sys.user.SysUserRemoveCommand;
import org.wu.spring.orm.integration.compare.application.command.sys.user.SysUserStoryCommand;
import org.wu.spring.orm.integration.compare.application.dto.SysUserDTO;
import org.wu.spring.orm.integration.compare.domain.model.sys.user.SysUser;
import org.wu.spring.orm.integration.compare.infrastructure.entity.OrmCompareRecordsDO;
import org.wu.spring.orm.integration.compare.infrastructure.entity.SysUserDO;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * describe sys_user
 *
 * @author Jia wei Wu
 * @date 2024/02/28 11:27 上午
 * @see org.wu.framework.lazy.orm.core.persistence.reverse.lazy.ddd.DefaultDDDLazyController
 **/
@Tag(name = "ORM 操作用户信息统计提供者")
@EasyController("/sys/user")
public class SysUserProvider {

    @Resource
    private SysUserApplication sysUserApplication;

    @Resource
    private LazyLambdaStream lazyLambdaStream;

    /**
     * describe 新增
     *
     * @return {@link Result <SysUser>} 新增后领域对象
     * @author Jia wei Wu
     * @date 2024/02/28 11:27 上午
     **/

    @Operation(summary = "新增、修改")
    @PostMapping("/story")
    public Result<SysUser> story() {
        // 模拟生成数据
        return sysUserApplication.story(DataTransformUntil.simulationBean(SysUserStoryCommand.class));
    }

    /**
     * describe 批量新增
     *
     * @param size 批量新增   数量
     * @return {@link Result<List<SysUser>>} 新增后领域对象集合
     * @author Jia wei Wu
     * @date 2024/02/28 11:27 上午
     **/

    @Operation(summary = "批量新增")
    @PostMapping("/batchStory")
    public Result<List<SysUser>> batchStory(@RequestParam(value = "size", defaultValue = "10") int size) {
        List<SysUserStoryCommand> sysUserStoryCommands = DataTransformUntil.simulationBeanList(SysUserStoryCommand.class, size);
        return sysUserApplication.batchStory(sysUserStoryCommands);
    }

    /**
     * describe 查询单个
     *
     * @param sysUserQueryOneCommand 查询单个
     * @return {@link Result<SysUserDTO>} DTO对象
     * @author Jia wei Wu
     * @date 2024/02/28 11:27 上午
     **/

    @Operation(summary = "查询单个")
    @GetMapping("/findOne")
    public Result<SysUserDTO> findOne(@ModelAttribute SysUserQueryOneCommand sysUserQueryOneCommand) {
        return sysUserApplication.findOne(sysUserQueryOneCommand);
    }

    /**
     * describe 查询多个
     *
     * @param sysUserQueryListCommand 查询多个
     * @return {@link Result<List<SysUserDTO>>} DTO对象
     * @author Jia wei Wu
     * @date 2024/02/28 11:27 上午
     **/

    @Operation(summary = "查询多个")
    @GetMapping("/findList")
    public Result<List<SysUserDTO>> findList(@ModelAttribute SysUserQueryListCommand sysUserQueryListCommand) {
        return sysUserApplication.findList(sysUserQueryListCommand);
    }

    /**
     * describe 分页查询多个
     *
     * @param sysUserQueryListCommand 分页查询多个
     * @return {@link Result<LazyPage<SysUserDTO>>} 分页DTO对象
     * @author Jia wei Wu
     * @date 2024/02/28 11:27 上午
     **/

    @Operation(summary = "分页查询多个")
    @GetMapping("/findPage")
    public Result<LazyPage<SysUserDTO>> findPage(@Parameter(description = "分页大小") @RequestParam(defaultValue = "10", value = "size") int size,
                                                 @Parameter(description = "当前页数") @RequestParam(defaultValue = "1", value = "current") int current, @ModelAttribute SysUserQueryListCommand sysUserQueryListCommand) {
        return sysUserApplication.findPage(size, current, sysUserQueryListCommand);
    }

    /**
     * describe 删除
     *
     * @param sysUserRemoveCommand 删除
     * @return {@link Result<SysUser>}
     * @author Jia wei Wu
     * @date 2024/02/28 11:27 上午
     **/

    @Operation(summary = "删除")
    @DeleteMapping("/remove")
    public Result<SysUser> remove(@ModelAttribute SysUserRemoveCommand sysUserRemoveCommand) {
        return sysUserApplication.remove(sysUserRemoveCommand);
    }

    /**
     * 一轮比对
     */
    @Transactional(rollbackFor = Exception.class)
    @Operation(summary = "一轮比对")
    @GetMapping("/oneRound")
    public void oneRound(@RequestParam(value = "size",defaultValue = "1") int size) {
        this.batchStory(size);
        this.findPage(size, 1, new SysUserQueryListCommand());

    }

    /**
     * 进行数据细节比较
     */
    @Operation(summary = "进行数据细节比较")
    @GetMapping("/run-particulars-compare")
    public void runParticularsCompare() {
        lazyLambdaStream.delete(LazyWrappers.<SysUserDO>lambdaWrapper().notNull(SysUserDO::getId));
        lazyLambdaStream.delete(LazyWrappers.<OrmCompareRecordsDO>lambdaWrapper().notNull(OrmCompareRecordsDO::getId));

        // 100000
        int totalSize = 20000;
        /**
         * 一轮比对
         */
        for (int i = 1; i < totalSize; i++) {
            this.oneRound(i);
        }
    }
    /**
     * 从一万开始进行数据细节比较
     */
    @Operation(summary = "从一万开始进行数据细节比较")
    @GetMapping("/run-particulars-compare-from-10000")
    public void runParticularsCompareFrom10000() {
        lazyLambdaStream.delete(LazyWrappers.<SysUserDO>lambdaWrapper().notNull(SysUserDO::getId));
        lazyLambdaStream.delete(LazyWrappers.<OrmCompareRecordsDO>lambdaWrapper().notNull(OrmCompareRecordsDO::getId));

        // 100000
        int totalSize = 20000;
        /**
         * 一轮比对
         */
        for (int i = 10000; i < totalSize; i++) {
            this.oneRound(i);
        }
    }

    /**
     * 快速进行数据比较
     */
    @Operation(summary = "快速进行数据比较")
    @GetMapping("/run-compare")
    public Result runCompare() {
//        Connection connection = DataSourceUtils.getConnection(dataSource);
//
//        DataSourceUtils.releaseConnection();
//         DataSourceUtils.isConnectionTransactional(con, dataSource);
//        StringUtils.startsWithIgnoreCase()
//        AnnotatedElementUtils.findMergedAnnotation()
//        AnnotatedElementUtils.getMergedAnnotation()


        // 删除就数据
        lazyLambdaStream.delete(LazyWrappers.<SysUserDO>lambdaWrapper().notNull(SysUserDO::getId));
        lazyLambdaStream.delete(LazyWrappers.<OrmCompareRecordsDO>lambdaWrapper().notNull(OrmCompareRecordsDO::getId));

        // 10 的幂数
        int power = 5;
        // 执行批量插入
        int size = 10;
        for (int i = 0; i < power; i++) {
            this.oneRound(size);
            size = size * 10;
        }
        return ResultFactory.successOf();
    }

    /**
     * 进行数据比较
     */
    @EasyFile(fileType = EasyFile.FileType.STRING_TYPE, suffix = "md", fileName = "比较mybatis、lazy、sqltoy、mybatis-flex操作数据")
    @Operation(summary = "进行数据比较")
    @GetMapping("/export-compare-result")
    public String exportCompareResult() {

        // 查询结果
        List<OrmCompareRecordsDO> ormCompareRecordsDOList = lazyLambdaStream
                .selectList(LazyWrappers.<OrmCompareRecordsDO>lambdaWrapper().notNull(OrmCompareRecordsDO::getId)
//                        .ignoreAs(OrmCompareRecordsDO::getOperationTime)
//                        .functionAs(" avg(operation_time) ",OrmCompareRecordsDO::getOperationTime)
                                .orderByAsc(OrmCompareRecordsDO::getAffectsRows)
                                .orderByAsc(OrmCompareRecordsDO::getOrm)
//                        .groupBy(OrmCompareRecordsDO::getOrm,OrmCompareRecordsDO::getType)
                );

        Map<String, Map<String, List<OrmCompareRecordsDO>>> collect = ormCompareRecordsDOList.stream()
                .collect(Collectors.groupingBy(OrmCompareRecordsDO::getType, Collectors.groupingBy(OrmCompareRecordsDO::getOrm)));


        // 转换成 md 文件 简略
        StringBuilder mdStringBuilder = new StringBuilder();

        collect.forEach((type, ormCompareRecordsDOS) -> {

            ormCompareRecordsDOS.forEach((orm, ormCompareRecordsDOList1) -> {
                //
                mdStringBuilder.append(NormalUsedString.PIPE);
                mdStringBuilder.append(orm).append("(").append(type).append(")");
                mdStringBuilder.append(NormalUsedString.PIPE);
                for (OrmCompareRecordsDO ormCompareRecordsDO : ormCompareRecordsDOList1) {
                    mdStringBuilder.append("影响行数:").append(ormCompareRecordsDO.getAffectsRows());
                    mdStringBuilder.append(NormalUsedString.PIPE);
                }
                mdStringBuilder.append(NormalUsedString.NEWLINE);


                mdStringBuilder.append(NormalUsedString.PIPE);
                for (int i = 0; i <= ormCompareRecordsDOList1.size(); i++) {
                    mdStringBuilder.append("---" + NormalUsedString.PIPE);
                }
                mdStringBuilder.append(NormalUsedString.NEWLINE);

                // 填充数据
                mdStringBuilder.append(NormalUsedString.PIPE);
                mdStringBuilder.append("执行时间:");
                mdStringBuilder.append(NormalUsedString.PIPE);
                for (OrmCompareRecordsDO ormCompareRecordsDO : ormCompareRecordsDOList1) {
                    mdStringBuilder.append("**");
                    mdStringBuilder.append(ormCompareRecordsDO.getOperationTime()).append("毫秒");
                    mdStringBuilder.append("**");
                    mdStringBuilder.append(NormalUsedString.PIPE);
                }
                mdStringBuilder.append(NormalUsedString.NEWLINE);


                // 填充数据
//                mdStringBuilder.append(NormalUsedString.PIPE);
//                mdStringBuilder.append("执行结果:");
//                mdStringBuilder.append(NormalUsedString.PIPE);
//
//                for (OrmCompareRecordsDO ormCompareRecordsDO : ormCompareRecordsDOList1) {
//                    mdStringBuilder.append(ormCompareRecordsDO.isSuccess());
//                    mdStringBuilder.append(NormalUsedString.PIPE);
//                }
                mdStringBuilder.append(NormalUsedString.NEWLINE);
                mdStringBuilder.append(NormalUsedString.NEWLINE);
                mdStringBuilder.append(NormalUsedString.NEWLINE);
                mdStringBuilder.append(NormalUsedString.NEWLINE);
            });


        });


        return mdStringBuilder.toString();
    }


}